//
//  ExchangeCouponsViewController.m
//  Truffle
//
//  Created by raca on 03/03/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "ExchangeCouponsViewController.h"
#import "DatasTruffle.h"
#import "DAOTruffle.h"

// GameKit Session ID for app
#define TRUFFLE_EXCHANGE_SESSION_ID @"TruffleExchangeCoupons"
#define truffleExchangeMaxPacketSize 1024
#define FIELDS_NUMBER 6


@implementation ExchangeCouponsViewController


@synthesize currentCoupon, exchangeSession, exchangePeerId;


- (id) initWithMyCoupon:(Coupon*)myCoupon andPeerStatus:(exchangeNetwork) aPeerStatus{
	self = [super init];
	if (self != nil) {
		if (myCoupon != nil) {
			currentCoupon = [myCoupon retain]; // if peerStatus is iServer, we must have a coupon to send
 		}else {
			currentCoupon = nil; // if peerStatus is iClient, we only receive
		}
		// le nombre de champs recu
		fieldsRecieved = 0;
		peerStatus = aPeerStatus;
		exchangeSession = nil;
		exchangePeerId = nil;		
	}
	return self;		
}


- (void)dealloc {
	// cleanup the session
	[self invalidateSession:self.exchangeSession];
	self.exchangeSession = nil;
	self.exchangePeerId = nil;
	// release the properties
	//	[currentCoupon release];
	//	[exchangePeerId release];
    [super dealloc];
}



/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
 if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
 // Custom initialization
 }
 return self;
 }
 */


#pragma mark -

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	[super viewDidLoad];
	self.title = @"Echange Bluetooth";
	
	NSString *uid = [[UIDevice currentDevice] uniqueIdentifier];
	exchangeUniqueID = [uid hash];
	
	[self startPicker];	
}


/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


#pragma mark -
#pragma mark GKPeerPickerController

// 
-(void)startPicker {
	GKPeerPickerController*		picker;
	
	picker = [[GKPeerPickerController alloc] init]; // note: picker is released in various picker delegate methods when picker use is done.
	picker.delegate = self;
	[picker show]; // show the Peer Picker
}



//
// Canceling connection 
//
- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker { 
	// Peer Picker automatically dismisses on user cancel. No need to programmatically dismiss.
    
	// autorelease the picker.
	picker.delegate = nil;
    [picker autorelease];
	
	// invalidate and release exchange session if one is around.
	if(self.exchangeSession != nil){
		[self invalidateSession:self.exchangeSession];
		self.exchangeSession = nil;
	}
	// go back to the previous view
	[[self navigationController]popViewControllerAnimated:YES]; 	
} 


//
// Provide a custom session that has a custom session ID. This is also an opportunity to provide a session with a custom display name.
//
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { 
	GKSession *session = [[GKSession alloc] initWithSessionID:TRUFFLE_EXCHANGE_SESSION_ID displayName:nil sessionMode:GKSessionModePeer]; 
	return [session autorelease]; // peer picker retains a reference, so autorelease ours so we don't leak.
}



- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session { 
	// Remember the current peer.
	self.exchangePeerId = peerID;  // copy
	// Make sure we have a reference to the truffle exchange session and it is set up
	self.exchangeSession = session; // retain
	self.exchangeSession.delegate = self; 
	[self.exchangeSession setDataReceiveHandler:self withContext:NULL];
	
	// Done with the Peer Picker so dismiss it.
	[picker dismiss];
	picker.delegate = nil;
	[picker autorelease];	
} 




#pragma mark -

//
// invalidate session
//
- (void)invalidateSession:(GKSession *)session {
	if(session != nil) {
		[session disconnectFromAllPeers]; 
		session.available = NO; 
		[session setDataReceiveHandler: nil withContext: NULL]; 
		session.delegate = nil; 
	}
}


#pragma mark -
#pragma mark Data Send/Receive Methods

/*
 * Getting a data packet. This is the data receive handler method expected by the GKSession. 
 * We set ourselves as the receive data handler in the -peerPickerController:didConnectPeer:toSession: method.
 */
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context { 		
	NSLog(@"******* [receiveData] reception d'un message du peer : %@", 
		  [session displayNameForPeer:peer]);
	switch (fieldsRecieved) {
		case 0:
			myIdCoupon = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			break;
		case 1:
			myName = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			break;
		case 2:
			myPosition = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			break;
		case 3:
			myProvider = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			break;
		case 4:
			myCouponCode = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			break;
		case 5:
			myDescriptions = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
			fieldsRecieved++;
			
			// une fois que les champs sont récupérés, on crée le coupon puis l'ajoute dans la base de données
			currentCoupon = [[Coupon alloc]initWithId:myIdCoupon 
												 name:myName 
											 position:myPosition 
											 provider:myProvider 
										   couponCode:myCouponCode 
										 descriptions:myDescriptions];
			// ajouter le coupon dans BDD
			[[DatasTruffle getDao] addCoupon:currentCoupon];
			// TODO : release the reseived coupon
			//... [currentCoupon release];
			NSLog(@"Reception of Coupon :  \n %@", currentCoupon);
			// afficher un message d'alerte
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Receive coupon" 
															message:[currentCoupon description] delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok",nil];
			[alert show];
			[alert release];
			[[self navigationController]popToRootViewControllerAnimated:YES];
			break;
		default:
			break;
	}
}


- (void)sendNetworkPacket:(GKSession *)session withData:(NSData *)data {
	NSLog(@"********* [sendNetworkPacket] Begin");
	NSString * toSend = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	[session sendData:data toPeers:[NSArray arrayWithObject:(id)exchangePeerId] withDataMode:GKSendDataReliable error:nil];
	NSLog(@"********* [sendNetworkPacket] Envoi de %@", toSend);
}


#pragma mark -
#pragma mark GKSessionDelegate Methods

// we've gotten a state change in the session
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { 
	NSLog(@"+++++ coucou je suis dans didChangeState");
	if(state == GKPeerStateDisconnected) {
		NSLog(@"********* [didChangeState][GKPeerStateDisconnected] %@ changes state" , [session displayNameForPeer:peerID]);
		// We've been disconnected from the other peer.
		//		[self finishExchange];
		[[self navigationController]popToRootViewControllerAnimated:YES]; 	
		// go back to start mode
		//TODO
	}
	if (state == GKPeerStateConnected ){
		NSLog(@"********* [didChangeState][GKPeerStateConnected] %@ changes state" , [session displayNameForPeer:peerID]);
		if (peerStatus == iServer) {
			[self sendCoupon];
		}
	}
	NSLog(@"+++++ coucou je sors de didChangeState");
	
}


- (void) sendCoupon{
	NSData* data;
	// bytes of the currentCoupon
	// send idCoupon
	data=[[currentCoupon idCoupon] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	// send name
	data=[[currentCoupon name] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	// send position
	data=[[currentCoupon position] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	// send provider
	data=[[currentCoupon provider] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	// send the couponCode
	data=[[currentCoupon couponCode] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	// send descriptions
	data=[[currentCoupon descriptions] dataUsingEncoding:NSUTF8StringEncoding];
	[self sendNetworkPacket:exchangeSession withData:data];
	
	// TODO: attendre l'aquitement de reception. Cet ack sera envoyé par le terminal
	// destination
	// ...
	// Une fois l'aquitement reçu, on supprime le coupon envoyé.
	[[DatasTruffle getDao] removeCoupon:currentCoupon];
	// TODO release the currentCoupon
	// ... [currentCoupon release];
	
	// afficher un message d'alerte
	NSLog(@"Sending of Coupon : \n %@ ", currentCoupon);
	UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send coupon" 
													message:[currentCoupon description] delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok",nil];
	[alert show];
	[alert release];
	[[self navigationController]popToRootViewControllerAnimated:YES];
}


- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID{
	NSLog(@"+++++ Yohoho in the session:didReceiveConnectionRequestFromPeer:");
}

- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error{
	NSLog(@"+++++ Yohoho in the session:didReceiveConnectionRequestFromPeer:");
}

- (void)session:(GKSession *)session didFailWithError:(NSError *)error{
	NSLog(@"+++++ Yohoho in the session:didFailWithError:");
}


@end